package com.linQing.waterWork.exception;

import com.linQing.waterWork.web.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.net.ConnectException;

@RestControllerAdvice
public class GlobalExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonResult<?> handleValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getDefaultMessage();
            }
        }
        return JsonResult.fail(ServiceCode.PARAMS_ERROR, message);
    }

    @ExceptionHandler(value = BindException.class)
    public JsonResult<?> handleValidException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField() + fieldError.getDefaultMessage();
            }
        }
        return JsonResult.fail(ServiceCode.INTERNAL_ERROR, message);
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public JsonResult<?> handlerNoFoundException(Exception e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(ServiceCode.NOT_FOUND_ERROR, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public JsonResult<?> handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(ServiceCode.INTERNAL_ERROR, "数据库中已存在该记录");
    }

    @ExceptionHandler(ServiceException.class)
    public JsonResult<?> serviceException(ServiceException e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(e.getServiceCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public JsonResult<?> handleException(Exception e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(ServiceCode.INTERNAL_ERROR, e.getMessage());
    }

    @ExceptionHandler(ConnectException.class)
    public JsonResult<?> connectException(ConnectException e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(ServiceCode.INTERNAL_ERROR, "系统调用异常");
    }

    @ExceptionHandler(ResourceAccessException.class)
    public JsonResult<?> connectException(ResourceAccessException e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(ServiceCode.INTERNAL_ERROR, "系统之间调用异常");
    }

    @ExceptionHandler(value = IllegalArgumentException.class)
    public JsonResult<?> illegalArgumentException(IllegalArgumentException e) {
        logger.error(e.getMessage(), e);
        return JsonResult.fail(ServiceCode.INTERNAL_ERROR, "Token非法参数异常");
    }

}